package org.fatewa.engine.design.genius;


import jakarta.servlet.http.HttpServletRequest;

/**
 * 对应 1.x 中的 Genius Hooks
 * 需要注意的是本次对 Hook 的类名称进行了调整，不再向下兼容
 *
 * @param <P> 主键类型
 * @param <T> 实体类型
 * @author 4everlynn
 */
public interface GenericHooks<T, P> {
    /**
     * 创建之前的 hook,
     * 与 1.x 不同的是，本次将 HttpServletRequest 回传可以让 Hook 在实现时更加灵活
     *
     * @param entity  领域数据
     * @param request 当前请求
     */
    default void beforeCreate(T entity, HttpServletRequest request) {
    }

    /**
     * 数据创建完毕的 hook
     *
     * @param entity  带有 ID 领域模型(数据库创建执行完毕)
     * @param success 是否成功
     */
    default void created(T entity, boolean success) {
    }

    /**
     * 更新之前的 hook
     *
     * @param entity  领域数据
     * @param request 当前请求
     */
    default void beforeUpdate(T entity, HttpServletRequest request) {
    }

    /**
     * 更新完毕的 hook
     *
     * @param entity  领域数据
     * @param success 是否成功
     */
    default void updated(T entity, boolean success) {
    }


    /**
     * 删除之前的 hook
     *
     * @param entity      被删除的数据
     * @param request 当前请求
     */
    default void beforeDelete(T entity, HttpServletRequest request) {
    }


    /**
     * 指定 Hook 是否开启事务，默认开启
     *
     * @return 是否开启事务
     */
    default boolean transactional() {
        return true;
    }

    /**
     * 删除之后的 hook
     *
     * @param entity      被删除的数据
     * @param success 是否成功
     */
    default void deleted(T entity, boolean success) {
    }

    /**
     * 指定是否异步执行, 默认是同步执行
     * 需要注意的是，异步执行虽然可以提高执行效率，
     * 但是并不是适合所有场景的，对于 hook 来说，大多数场景下还是同步执行会更加通用
     *
     * @return 是否异步执行
     */
    default boolean async() {
        return false;
    }


    /**
     * 决定 Hook 的执行顺序，越小优先级越高
     *
     * @return Hook 的执行顺序
     */
    default int order() {
        return 0;
    }
}
